package com.nbcio.iot.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nbcio.iot.queue.IotMessageQueueService;
import com.nbcio.iot.rule.RuleRuntimeService;
import com.nbcio.iot.service.NodeRedService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Map;
import com.nbcio.common.tenant.helper.TenantHelper;

/**
 * IoT 规则执行服务
 * 从消息队列消费消息并执行规则
 *
 * @author nbacheng
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class IotRuleExecutionService {

    private final IotMessageQueueService messageQueueService;
    private final RuleRuntimeService ruleRuntimeService;
    private final NodeRedService nodeRedService;
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 定时消费规则执行消息 - 每1秒执行一次
     */
    @Scheduled(fixedDelayString = "1000")
    public void processRuleExecution() {
        try {
            String messageJson = messageQueueService.consumeRuleExecutionMessage();
            if (messageJson != null) {
                processMessage(messageJson);
            }
        } catch (Exception e) {
            log.error("[RULE-EXECUTION] 处理规则执行消息失败: {}", e.getMessage());
        }
    }

    /**
     * 处理单条消息
     */
    @Async
    public void processMessage(String messageJson) {
        try {
            Map<String, Object> message = objectMapper.readValue(messageJson, Map.class);
            String deviceCode = (String) message.get("deviceCode");
            Long flowId = message.get("flowId") == null ? null : Long.valueOf(String.valueOf(message.get("flowId")));
            String tenantId = (String) message.get("tenantId");

            if (flowId == null) {
                log.warn("[RULE-EXECUTION] 设备 {} 没有配置规则", deviceCode);
                return;
            }

            TenantHelper.dynamic(tenantId, () -> {
                // 获取规则配置
                Map<String, Object> flowConfig = nodeRedService.getFlowConfigById(flowId);
                if (flowConfig == null || flowConfig.isEmpty()) {
                    log.warn("[RULE-EXECUTION] 设备 {} 规则配置不存在", deviceCode);
                    return;
                }
                // 执行规则
                ruleRuntimeService.process(message, flowConfig);
                log.info("[RULE-EXECUTION] 设备 {} 规则执行完成", deviceCode);
            });

        } catch (Exception e) {
            log.error("[RULE-EXECUTION] 处理消息失败: {}", e.getMessage());
        }
    }
}
